#!/usr/bin/perl

#
#       Copyright (C) 2008-2012 Александр Девяткин, "Зелёная горка"
#
#       Разрешается повторное распространение и использование как в виде исходного
#       кода, так и в двоичной форме, с изменениями или без, при соблюдении следующих
#       условий:
#
#       * При повторном распространении исходного кода должно оставаться указанное
#         выше уведомление об авторском праве, этот список условий и последующий
#         отказ от гарантий.
#       * При повторном распространении двоичного кода должна сохраняться указанная
#         выше информация об авторском праве, этот список условий и последующий отказ
#         от гарантий в документации и/или в других материалах, поставляемых при
#         распространении.
#       * Ни название "Зелёная горка", ни имена ее сотрудников не могут быть
#         использованы в качестве поддержки или продвижения продуктов, основанных
#         на этом ПО без предварительного письменного разрешения.
#
#       ЭТА ПРОГРАММА ПРЕДОСТАВЛЕНА ВЛАДЕЛЬЦАМИ АВТОРСКИХ ПРАВ И/ИЛИ ДРУГИМИ СТОРОНАМИ
#	"КАК ОНА ЕСТЬ" БЕЗ КАКОГО-ЛИБО ВИДА ГАРАНТИЙ, ВЫРАЖЕННЫХ ЯВНО ИЛИ ПОДРАЗУМЕВАЕМЫХ,
#	ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ, ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ КОММЕРЧЕСКОЙ ЦЕННОСТИ
#	И ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ. НИ В КОЕМ СЛУЧАЕ, ЕСЛИ НЕ ТРЕБУЕТСЯ
#	СООТВЕТСТВУЮЩИМ ЗАКОНОМ, ИЛИ НЕ УСТАНОВЛЕНО В УСТНОЙ ФОРМЕ, НИ ОДИН ВЛАДЕЛЕЦ
#	АВТОРСКИХ ПРАВ И НИ ОДНО ДРУГОЕ ЛИЦО, КОТОРОЕ МОЖЕТ ИЗМЕНЯТЬ И/ИЛИ ПОВТОРНО
#	РАСПРОСТРАНЯТЬ ПРОГРАММУ, КАК БЫЛО СКАЗАНО ВЫШЕ, НЕ НЕСЁТ ОТВЕТСТВЕННОСТИ,
#	ВКЛЮЧАЯ ЛЮБЫЕ ОБЩИЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ ИЛИ ПОСЛЕДОВАВШИЕ УБЫТКИ,
#	ВСЛЕДСТВИЕ ИСПОЛЬЗОВАНИЯ ИЛИ НЕВОЗМОЖНОСТИ ИСПОЛЬЗОВАНИЯ ПРОГРАММЫ (ВКЛЮЧАЯ,
#	НО НЕ ОГРАНИЧИВАЯСЬ ПОТЕРЕЙ ДАННЫХ, ИЛИ ДАННЫМИ, СТАВШИМИ НЕПРАВИЛЬНЫМИ, ИЛИ
#	ПОТЕРЯМИ ПРИНЕСЕННЫМИ ИЗ-ЗА ВАС ИЛИ ТРЕТЬИХ ЛИЦ, ИЛИ ОТКАЗОМ ПРОГРАММЫ РАБОТАТЬ
#	СОВМЕСТНО С ДРУГИМИ ПРОГРАММАМИ), ДАЖЕ ЕСЛИ ТАКОЙ ВЛАДЕЛЕЦ ИЛИ ДРУГОЕ ЛИЦО БЫЛИ
#	ИЗВЕЩЕНЫ О ВОЗМОЖНОСТИ ТАКИХ УБЫТКОВ.
#

#       Copyright (C) 2008-2012 Aleksandr Deviatkin, "Green Hill"
#
#       Redistribution and use in source and binary forms, with or without
#       modification, are permitted provided that the following conditions are
#       met:
#       
#       * Redistributions of source code must retain the above copyright
#         notice, this list of conditions and the following disclaimer.
#       * Redistributions in binary form must reproduce the above
#         copyright notice, this list of conditions and the following disclaimer
#         in the documentation and/or other materials provided with the
#         distribution.
#       * Neither the name of the Green Hill nor the names of its
#         contributors may be used to endorse or promote products derived from
#         this software without specific prior written permission.
#       
#       THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
#       "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
#       LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
#       A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
#       OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#       SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#       LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
#       DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
#       THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#       (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
#       OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#


$|=1;
use DBI;
use Date::Manip;
use strict;

#
# Ежемесячное обновление таблицы расходов по счетчикам
# 2014-05-06 alid
#

my (@args, %opts);
foreach(@ARGV){
	if(/^\-(\S)(\S*)/) { $opts{$1} = $2; } else {  push @args, $_; }
}
my ($database) = (@args);
die "Usage: $0 database"		unless($database);
my $verb = exists $opts{v};
my $full = exists $opts{f};	# полное обновление таблицы
my $pgport = 5432;

my $dbh = DBI->connect("dbi:Pg:dbname=$database;port=$pgport","","", { RaiseError => 1, AutoCommit => 0});
my $sth = $dbh->prepare("SELECT id FROM counters");
my $sel = $dbh->prepare("SELECT id,(SELECT COUNT(*) FROM mexpenses WHERE cid=? AND year=? AND month=?) FROM mexpenses WHERE cid=? AND year=? AND month=?");
my $upd = $dbh->prepare("UPDATE mexpenses SET exp1=?,exp2=?,modtime=now() WHERE id=?");
my $ins = $dbh->prepare("INSERT INTO mexpenses (cid,year,month,exp1,exp2) VALUES (?,?,?,?,?)");
my $del = $dbh->prepare("DELETE FROM mexpenses WHERE cid=? AND year=? AND month=?");

# Список счетчиков
my @List;
$sth->execute();
while(my ($r) = $sth->fetchrow_array) { push @List,$r;} $sth->finish;

if($full) {	# полное обновление
	$sth = $dbh->prepare("SELECT dt,se1ai,se2ai FROM monitor WHERE counter=? AND dt LIKE '%-01 %' ORDER BY dt DESC");
	print "Full update\n"	if $verb;
} else {	# только последний месяц
	# FreeBSD only:
	#my $lm = `date -v-1m "+%Y-%m"`; chomp $lm;

	my $edate = UnixDate("today","%Y-%m");
	my $sdate = UnixDate("1 month ago","%Y-%m");
	$sth = $dbh->prepare("SELECT dt,se1ai,se2ai FROM monitor WHERE counter=? AND ((dt>'$sdate-01 00:00:00' AND dt<'$sdate-01 23:59:59') OR (dt>'$edate-01 00:00:00' AND dt<'$edate-01 23:59:59')) ORDER BY dt DESC");
	print "Last month: $sdate - $edate\n"	if $verb;
}

foreach my $cid (@List) {
	print "cid=$cid\n"	if $verb;
	$sth->execute($cid);
	my $Data;
	while(my $r = $sth->fetchrow_hashref) {
		my ($year, $mon) = ($r->{dt} =~ m/^(\d{4})\-(\d{2})/);
		$Data->{$year}->{$mon} = $r;
	}
	$sth->finish;

	my ($data1,$data2);
	foreach my $year (sort {$b<=>$a} keys %$Data) {
		foreach my $mon (sort {$b<=>$a} keys %{$Data->{$year}}) {
			if(defined $data1) {
				print "$year $mon ".($data1 - $Data->{$year}->{$mon}->{se1ai})." ".($data2 - $Data->{$year}->{$mon}->{se2ai})."\n"	if $verb;
				setdata($cid,$year,$mon,$data1 - $Data->{$year}->{$mon}->{se1ai},$data2 - $Data->{$year}->{$mon}->{se2ai});
			}
			($data1,$data2) = ($Data->{$year}->{$mon}->{se1ai},$Data->{$year}->{$mon}->{se2ai});
		}
	}
#last;
}
$dbh->commit;
$dbh->disconnect;

sub setdata {
	my ($cid,$year,$month,$exp1,$exp2) = @_;
	$sel->execute($cid,$year,$month,$cid,$year,$month);
	my ($id,$count) = ($sel->fetchrow_array);
	$sel->finish;
	if($id && $count == 1) {
		$upd->execute($exp1,$exp2,$id);
	} else {
		$del->execute($cid,$year,$month)	if($count > 1);
		$ins->execute($cid,$year,$month,$exp1,$exp2);
	}
}


